package com.zretc.config;

import com.zretc.entity.Permission;
import com.zretc.entity.Role;
import com.zretc.service.UserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.Collection;
import java.util.List;

/**
 * @author 周文涛
 * 2020年8月21日11:42:48
 * 根据请求路径查询可以访问的角色
 */
@Component
public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Autowired
    private UserInfoService userInfoService;

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        // 从形参中获取请求路径
        String requestUrl = ((FilterInvocation) o).getRequestUrl();
        // 从数据库中获取全部权限路径并配对
        List<Permission> permissions = userInfoService.getAllPermission();
        for (Permission permission : permissions) {
            // 配对路径
            if(antPathMatcher.match(permission.getUrl(),requestUrl)){
                // 如果配对成功，则获取可以访问的角色
                List<Role> roles = permission.getRoles();
                // 转换为字符数组
                String[] array = new String[roles.size()];
                for(int i = 0; i< roles.size(); i++){
                    array[i] = roles.get(i).getRoleName();
                }
                // 存储进SecurityConfig
                return SecurityConfig.createList(array);

            }
        }
        // 如果不匹配，返回 固定权限ROLE_LOGIN
        return SecurityConfig.createList("ROLE_LOGIN");
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return true;
    }
}
